package main

import (
	"crypto/tls"
	"flag"
	"fmt"
	"log"
	"os"
	"runtime"
	"thais/database/redis"
	tlog "thais/tunnel/log"
	"thais/utils"
	"thais/utils/jwt"
	"thais/webproxy"

	ts "thais/tunnel/server"

	"github.com/bugfan/goini"
	"github.com/bugfan/to"
)

var (
	debug string
)

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	//  init configer
	if os.Getenv("ENV_FILE") != "" {
		goini.Env = goini.NewMyEnv(os.Getenv("ENV_FILE"))
	} else {
		goini.Env = goini.NewMyEnv()
	}
	// debug mod
	flag.StringVar(&debug, "debug", "false", "Set Debug Mode")
	flag.Parse()
	webproxy.Debug = to.Bool(debug)
}

func main() {
	// init logger
	utils.InitLog()
	// init jwt config
	jwt.InitJWTConf()
	// init redis
	redis.Proxy = &redis.Redis{}
	redis.Proxy.ConnRedis("WEBPROXY")
	redis.WhiteList = &redis.Redis{}
	redis.WhiteList.ConnRedis("whitelist")

	go func() {
		proxy := webproxy.NewWebProxy()
		proxy.InjectJs(true)
		c := webproxy.NewDefaultConfig()
		c.Addr = goini.Env.Getenvd("PROXY_ADDR", "0.0.0.0")
		c.Scheme = "http"
		c.Middle = goini.Env.Getenvd("PROXY_MIDDLE_PATH", c.Middle)
		c.Port = goini.Env.Getenvd("PROXY_PORT", "8080")
		c.OtherPort = goini.Env.Getenvd("PROXY_OTHERPORT", "9090")
		log.Println(proxy.Run(c))
	}()

	go func() {
		proxy := webproxy.NewWebProxy()
		proxy.InjectJs(true)
		c := webproxy.NewDefaultConfig()
		c.Addr = goini.Env.Getenvd("PROXY_HTTPS_ADDR", "0.0.0.0")
		c.Scheme = "https"
		c.Middle = goini.Env.Getenvd("PROXY_MIDDLE_PATH", c.Middle)
		c.Port = goini.Env.Getenvd("PROXY_PORT", "9090")
		c.OtherPort = goini.Env.Getenvd("PROXY_OTHERPORT", "8080")
		c.KeyPath = goini.Env.Getenvd("PROXY_HTTPS_KEY", "./key.pem")
		c.CertPath = goini.Env.Getenvd("PROXY_HTTPS_CERT", "./cert.pem")
		log.Println(proxy.Run(c))
	}()

	if runtime.GOOS == "darwin" || runtime.GOOS == "linux" {
		tlog.LogTo("stdout", "")
	} else {
		tlog.LogTo("syslog", "INFO")
	}
	go func() {
		tunnelListen := fmt.Sprintf("%s:%s", "127.0.0.1", "4433")
		keyPEM, err := utils.Asset("cert/tunnel.key")
		if err != nil {
			return
		}
		certPEM, err := utils.Asset("cert/tunnel.crt")
		if err != nil {
			return
		}
		tlsConf := ts.LoadTLSConfigFromBytes(certPEM, keyPEM)
		if tlsConf != nil {
			tlsConf.ClientSessionCache = tls.NewLRUClientSessionCache(5000)
		}
		ts.TunnelListener(tunnelListen, tlsConf)
	}()
	<-(chan int)(nil)
}
